import s from './index.module.less'
import {Button, CardGroup, Col, Descriptions, Form, Modal, Popconfirm, Row, Switch, Tag, Typography}
    from
        "@douyinfe/semi-ui";
import {IconDelete, IconEdit, IconPlus} from "@douyinfe/semi-icons";
import React, {useEffect, useRef, useState} from "react";
import {AiConfig} from "@/schemas/ai.ts";
import {FormApi, FormFCChild, RuleItem} from "@douyinfe/semi-ui/lib/es/form";
import {AppDispatch, RootState} from "@/redux/store.ts";
import {useDispatch, useSelector} from "react-redux";
import {CreateAiConfig, DeleteAiConfig, ListAiConfig, SetCurrentAiConfig, UpdateAiConfig} from "@/service/ai.ts";
import {Card} from "@douyinfe/semi-ui";
import type {Data} from "@douyinfe/semi-ui/lib/es/descriptions";
import {TagColor} from "@douyinfe/semi-ui/lib/es/tag";
import {queryTen} from "@/common/default-some.ts";

interface ModalFormProps {
    visible: boolean;
    setVisible: (visible: boolean) => void;
    initialValue?: AiConfig;
}

const ModalForm = (
    {
        visible, setVisible, initialValue,
    }: ModalFormProps
) => {

    const formRef = useRef<FormApi<AiConfig>>();

    const requiredRule: RuleItem = {required: true, message: '这里必须填点什么哦~'};

    const kindOptions = [
        {label: 'OpenAI', value: 'openai'},
        {label: 'Ollama', value: 'ollama'},
    ]

    const notRequiredHelpText = "此项非必需，若您不清楚可不填"

    const getInfoByOperatorHelpText = "若您使用在厂商处购买的AI产品，或许可以在其网站上找到该信息"

    const dispatch = useDispatch<AppDispatch>();

    const numberInputDefaultProps = {
        extraText: notRequiredHelpText,
        precision: 1,
        step: 0.1,
        max: 1,
        min: 0
    }

    const handleSubmit = async () => {
        const data = await formRef.current?.validate()
        if (!data) return

        // 设置默认值
        data.topP = data.topP || 0.2
        data.temperature = data.temperature || 0.1

        if (initialValue?.id) dispatch(UpdateAiConfig({...data, id: initialValue.id} as AiConfig))
        else dispatch(CreateAiConfig(data as AiConfig))
        setVisible(false);
    }

    return <Modal
        onOk={handleSubmit}
        visible={visible}
        onCancel={() => setVisible(false)}
        width={600}
        title={`${initialValue?.id ? "修改" : "创建"}配置`}
    >
        <Form
            extraTextPosition={'middle'}
            initValues={initialValue}
            getFormApi={formApi => formRef.current = formApi}
        >
            {
                ({formState}: FormFCChild<AiConfig>) => <React.Fragment>

                    <Form.Input field={'name'} label={'配置名称'} rules={[requiredRule]}/>

                    <Form.Select
                        label={'接入类型'}
                        rules={[requiredRule]}
                        field={'kind'}
                        style={{width: '100%'}}
                        extraText={'如果您不清楚 Ollama 是什么则选择 OpenAI'}
                        optionList={kindOptions}
                    />

                    <Form.Input
                        extraText={getInfoByOperatorHelpText}
                        rules={[requiredRule]}
                        label={'Base url'}
                        field={'baseUrl'}
                    />

                    {formState.values?.kind === 'openai' ?
                        <Form.Input
                            extraText={getInfoByOperatorHelpText}
                            rules={[requiredRule]}
                            label={'Api key'}
                            field={'apiKey'}
                        /> :
                        null}

                    <Form.Input
                        extraText={getInfoByOperatorHelpText}
                        rules={[requiredRule]}
                        label={'模型名称'}
                        field={'model'}
                    />

                    <Row gutter={16}>
                        <Col span={12}>
                            <Form.InputNumber
                                label={'Temperature'}
                                field={'temperature'}
                                {...numberInputDefaultProps}
                            />
                        </Col>
                        <Col span={12}>
                            <Form.InputNumber
                                label={'Top-P'} field={'topP'}
                                {...numberInputDefaultProps}
                            />
                        </Col>
                    </Row>


                </React.Fragment>
            }
        </Form>

    </Modal>
}


const Ai = () => {

    const [formVisible, setFormVisible] = useState(false)

    const {list} = useSelector((state: RootState) => state.ai)

    const [formInitial, setFormInitial] = useState<AiConfig|undefined>(undefined)

    const dispatch = useDispatch<AppDispatch>();

    useEffect(() => {
        dispatch(ListAiConfig(queryTen))
    }, []);

    const renderItem = (item: AiConfig, index: number) => {

        const kindTagMap = {
            'ollama': {color: 'cyan', text: 'Ollama'},
            'openai': {color: 'pink', text: 'OpenAI'},
        }

        const tagColor = kindTagMap[item.kind].color as TagColor

        const tagText = kindTagMap[item.kind].text

        const ellipsisText = (t: string) => <Typography.Text
            ellipsis={{showTooltip: true}}
            style={{width: 186}}
        >{t}</Typography.Text>

        const descData: Data[] = [
            {key: '接入类型', value: <Tag color={tagColor}>{tagText}</Tag>},
            {key: '模型名称', value: item.model},
            {key: 'Base url', value: ellipsisText(item.baseUrl)},
            {key: 'Api key', value: ellipsisText(item.apiKey || "")},
            {key: 'Temperature', value: item.temperature},
            {key: 'Top-P', value: item.topP},
        ]

        const onDelete = async () => {
            dispatch(DeleteAiConfig(item.id || ""))
        }

        const handleEdit = async () => {
            setFormInitial(item)
            setFormVisible(true)
        }

        const handleSwitch = async (checked: boolean) => {
            if (checked) dispatch(SetCurrentAiConfig(item.id || ""))
        }

        return <Card
            key={`config-item-${index}`}
            className={s.cardBox}
            headerStyle={{padding: 0}}
            bodyStyle={{paddingBottom: 0}}
            header={<div className={s.cardHeader}>
                <Typography.Text
                    strong
                    ellipsis={true}
                    style={{width: 'calc(100% - 60px)'}}
                >{item.name}</Typography.Text>
                <Switch
                    size={'small'}
                    onChange={handleSwitch}
                    checked={!!item.currentUse}
                />
            </div>}
            footerStyle={{padding: 0}}
            footer={<div className={s.cardHeader}>
                <Button
                    style={{width: 'calc(80% - 4px)'}}
                    icon={<IconEdit/>}
                    onClick={handleEdit}
                />
                <Popconfirm
                    title="确定删除吗？"
                    content="此操作将不可逆"
                    onConfirm={onDelete}
                    position={'topRight'}
                    showArrow
                >
                    <Button style={{width: 'calc(20% - 4px)'}} type={'danger'} icon={<IconDelete/>}/>
                </Popconfirm>
            </div>}
        >
            <Descriptions align={'justify'} data={descData} style={{width: '100%'}}/>
        </Card>
    }

    return <div className={s.container}>

        <CardGroup spacing={8}>
            {list.map(renderItem)}
        </CardGroup>

        <div className={s.operations}>
            <Button icon={<IconPlus/>} onClick={() => {
                setFormInitial(undefined);
                setFormVisible(true)
            }}/>
        </div>

        <ModalForm visible={formVisible} initialValue={formInitial} setVisible={setFormVisible}/>

    </div>;
}

export default Ai;